package com.fileupload.upload.log.strategy;

import com.fileupload.model.entity.FileUploadLog;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Redis日志存储策略实现
 * 使用Redis进行日志存储，将日志对象序列化为JSON格式
 */
@Component("redisLogStorageStrategy")
public class RedisLogStorageStrategy implements LogStorageStrategy {
    
    private static final Logger logger = LoggerFactory.getLogger(RedisLogStorageStrategy.class);
    
    // Redis key前缀
    private static final String REDIS_LOG_KEY_PREFIX = "fileupload:logs:";
    
    // 默认过期时间（7天）
    private static final long DEFAULT_EXPIRE_DAYS = 7;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Override
    public boolean storeLog(FileUploadLog log) {
        if (log == null) {
            logger.warn("[Redis存储] 日志对象为空，跳过存储");
            return false;
        }
        
        try {
            String logJson = objectMapper.writeValueAsString(log);
            String redisKey = getRedisKey();
            
            // 添加到Redis列表
            redisTemplate.opsForList().rightPush(redisKey, logJson);
            logger.info("[Redis存储] 单条日志存储成功 - 文件名: {}", log.getUploadFileName());
            
            // 设置过期时间
            redisTemplate.expire(redisKey, DEFAULT_EXPIRE_DAYS, TimeUnit.DAYS);
            
            return true;
        } catch (Exception e) {
            logger.error("[Redis存储] 单条日志存储失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    public boolean batchStoreLogs(List<FileUploadLog> logs) {
        if (logs == null || logs.isEmpty()) {
            logger.warn("[Redis存储] 日志列表为空，跳过批量存储");
            return false;
        }
        
        try {
            logger.info("[Redis存储] 开始执行Redis批量存储，记录数: {}", logs.size());
            long startTime = System.currentTimeMillis();
            
            String redisKey = getRedisKey();
            int successCount = 0;
            
            // 批量插入到Redis
            for (FileUploadLog log : logs) {
                try {
                    String logJson = objectMapper.writeValueAsString(log);
                    redisTemplate.opsForList().rightPush(redisKey, logJson);
                    successCount++;
                } catch (Exception e) {
                    logger.error("[Redis存储] 单条日志序列化失败: {}", e.getMessage());
                }
            }
            
            // 设置过期时间
            redisTemplate.expire(redisKey, DEFAULT_EXPIRE_DAYS, TimeUnit.DAYS);
            
            long endTime = System.currentTimeMillis();
            logger.info("[Redis存储] 批量存储完成 - 总记录数: {}, 成功: {}, 失败: {}, 耗时: {}ms", 
                    logs.size(), successCount, logs.size() - successCount, (endTime - startTime));
            
            return successCount > 0;
        } catch (Exception e) {
            logger.error("[Redis存储] 批量存储异常: {}", e.getMessage(), e);
            throw e; // 抛出异常让调用方处理
        }
    }
    
    @Override
    public String getType() {
        return "redis"; // 返回策略类型标识
    }
    
    /**
     * 获取Redis存储的key
     * @return Redis key
     */
    private String getRedisKey() {
        // 可以根据日期分桶存储
        String date = java.time.LocalDate.now().toString();
        return REDIS_LOG_KEY_PREFIX + date;
    }
}